﻿using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace vf_test
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void ShowInfo(string info)
        {
            tbInfo.Text = info;
        }

        /// <summary>
        /// 提取坐标点集
        /// </summary>
        /// <param name="points"></param>
        /// <returns></returns>
        private int ExtractPoints(out List<Point3D> points)
        {
            points = new List<Point3D>();
            string input = tbInputCoord.Text;
            string[] parts = input.Split(';');
            foreach (string part in parts)
            {
                Point3D pt = Point3D.From(part);
                points.Add(pt);
            }        
            return points.Count;
        }

        /// <summary>
        /// 提取ID集
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        private int ExtractIds(out List<UInt64> ids)
        {
            ids = new List<UInt64>();
            string input = tbInputIds.Text;
            string[] parts = input.Split(',');
            foreach (string part in parts)
            {
                UInt64 id = UInt64.Parse(part);
                ids.Add(id);
            }
            return ids.Count;
        }
        
        /// <summary>
        /// 提取双精度浮点值
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        private int ExtractDoubleValues(out List<Double> values) {
            values = new List<Double>();
            string input = tbInputDouble.Text;
            string[] parts = input.Split(',');
            foreach (string part in parts)
            {
                Double value = Double.Parse(part);
                values.Add(value);
            }
            return values.Count;
        }


        /// <summary>
        /// 提取字符串集
        /// </summary>
        /// <param name="strArr"></param>
        /// <returns></returns>
        private int ExtractString(out List<string> strArr)
        {
            strArr = new List<string>();
            string input = tbInputStr.Text;
            string[] parts = input.Split(',');
            foreach (string part in parts)
            {
                strArr.Add(part);
            }
            return strArr.Count;
        }

        const int TGC_CODE = 2;
        private void btnLinkCad_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                VfHRESULT status = VFAdapter.vfStartLinkWithCAD(TGC_CODE);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo("连接天工CAD成功");
                }
                else
                {
                    ShowInfo("连接天工CAD失败");
                }
            }
            catch (Exception ex)
            {
                ShowInfo (ex.Message);
            }
        }

        private void btnCtPt_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int ptCnt= ExtractPoints(out List<Point3D> points);
                if(ptCnt!=1)
                {
                    ShowInfo("请输入要创建的点的坐标");
                    return;
                }
                VfHRESULT status = VFAdapter.vfCreatePoint(points[0].x, points[0].y, points[0].z,out UInt64 ptID);
                if(status==VfHRESULT.vf_Success)
                {
                    ShowInfo("创建点成功，ID为："+(UInt64)ptID);
                }
                else
                {
                    ShowInfo("创建点失败");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }

        private void btmCvCvi_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                bool createPoint = chkCreteaPoint.IsChecked.HasValue?chkCreteaPoint.IsChecked.Value:false;
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt != 2)
                {
                    ShowInfo("请仅输入两个实体的ID");
                    return;
                }
                UInt64 cvIdFst = ids[0];
                UInt64 cvIdSnd = ids[1];
                VfHRESULT status = VFAdapter.vfCurveCurveIntersection(cvIdFst, cvIdSnd, out double x, out double y, out double z, createPoint, out UInt64 ptID);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo(string.Format("计算交点成功，交点为:{0:F3},{1:F3},{2:F3},交点ID{3}", x,y,z,ptID));
                }
                else
                {
                    ShowInfo("计算交点失败");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }

        private void btnGetType_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if(idCnt!=1)
                {
                    ShowInfo("请仅输入一个实体的ID");
                    return;
                }

                UInt64 id = ids[0];
                VfHRESULT status = VFAdapter.vfGetEntityType(id, out GeomEntityType enType);
                if (status == VfHRESULT.vf_Success)
                {
                    string typeStr = "";
                    switch (enType)
                    {
                        case GeomEntityType.vf_face:
                            {
                                typeStr = "面";
                                break;
                            }
                        case GeomEntityType.vf_curve:
                            {
                                typeStr = "曲线";
                                break;
                            }

                        case GeomEntityType.vf_vertex:
                            {
                                typeStr = "点";
                                break;
                            }
                    }
                    ShowInfo("该实体类型为：" + typeStr);
                }else
                {
                    ShowInfo("获取实体类型失败");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }

        }

        private void btnSelByTag_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt != 1)
                {
                    ShowInfo("请仅输入一个实体的ID");
                    return;
                }

                UInt64 id = ids[0];
                VfHRESULT status = VFAdapter.vfSelectByTag(id);
                if(status == VfHRESULT.vf_Success)
                {
                    ShowInfo(id+"已加入选择集");
                }else
                {
                    ShowInfo(id+"未选中");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }

        }

        private void btnClrSSet_Click(object sender, RoutedEventArgs e)
        {
            try
            {         
                VfHRESULT status = VFAdapter.vfClearSeletion();
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo("已清空选择集");
                }
                else
                {
                    ShowInfo("未能清空选择集");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }

        private GeomEntityType ConvertFileType(int idx)
        {
            // vertex
            if (idx == 0)
                return GeomEntityType.vf_vertex;

            if (idx == 1)
                return GeomEntityType.vf_curve;

            if (2 == idx)
                return GeomEntityType.vf_face;

            if (3 == idx)
                return GeomEntityType.vf_body;

            return GeomEntityType.vf_geom_none;
        }

        private string ContructPromptStr(GeomEntityType geomType,bool isMultiple=false)
        {
            string endStr = ",右键确认并退出";
            switch(geomType) {
                case GeomEntityType.vf_vertex:
                    return "请选择点"+(isMultiple?endStr:"");
                case GeomEntityType.vf_face:
                    return "请选择面" + (isMultiple ? endStr : "");
                case GeomEntityType.vf_body:
                    return "请选择体" + (isMultiple ? endStr : "");
                case GeomEntityType.vf_curve:
                    return "请选择边" + (isMultiple ? endStr : "");
                default:
                    return "";
            }
        }

        private void btnSelSingle_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int selIdx= cbFilterType.SelectedIndex;
                GeomEntityType filterType = ConvertFileType(selIdx);
                if(filterType == GeomEntityType.vf_geom_none)
                {
                    ShowInfo("未处理的索引");
                    return;
                }
                bool preSelection = chkPreselection.IsChecked.HasValue ? chkPreselection.IsChecked.Value : false;
                string promptStr = ContructPromptStr(filterType);
                VfHRESULT status = VFAdapter.vfSelectSingleByInteractive(filterType, out UInt64 tagID, promptStr, preSelection);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo("已选择" + tagID);
                }
                else
                {
                    ShowInfo("已取消或未选中");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }

        private void btnCtOfsCv_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt != 2)
                {
                    ShowInfo("请仅输入两个实体的ID,第一个为曲线ID,第二个为曲面ID");
                    return;
                }
                int disCnt = ExtractDoubleValues(out List<double> disArr);
                if (disCnt != 1)
                {
                    ShowInfo("请仅输入一个距离值");
                    return;
                }
                UInt64 cvIdFst = ids[0];
                UInt64 surfId = ids[1];
                double dis = disArr[0];
                VfHRESULT status = VFAdapter.vfOffsetCurve(cvIdFst, surfId, dis, out UInt64 outCvId);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo("曲线在曲面上偏移成功，新生成的曲线ID为:" + outCvId);
                }
                else
                {
                    ShowInfo("曲线在曲面上偏移失败");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }

        }

        private void btnCvSurfi_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt != 2)
                {
                    ShowInfo("请仅输入两个实体的ID,第一个为曲线ID,第二个为曲面ID");
                    return;
                }
              
                UInt64 cvIdFst = ids[0];
                UInt64 surfId = ids[1];
                bool createPoint = chkCreteaPoint.IsChecked.HasValue ? chkCreteaPoint.IsChecked.Value : false;
                VfHRESULT status = VFAdapter.vfCurveSurfaceIntersection(cvIdFst, surfId,out double x,out double y,out double z, createPoint, out UInt64 outPtId);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo(string.Format("计算曲线与曲面交点成功，交点为:{0:F3},{1:F3},{2:F3},交点ID{3}", x, y, z, outPtId));
                }
                else
                {
                    ShowInfo("计算曲线与曲面交点成功交点有误");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }

        }

        private void btnSurfSurfi_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt != 2)
                {
                    ShowInfo("请仅输入两个实体的ID,第一个为曲线ID,第二个为曲面ID");
                    return;
                }

                UInt64 surfIdFst = ids[0];
                UInt64 surfIdScd = ids[1];

                VfHRESULT status = VFAdapter.vfCreateCurveBySurfaceIntersection(surfIdFst, surfIdScd, out UInt64 outCvId);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo("计算曲面交线成功，交线ID为:" + outCvId);
                }
                else
                {
                    ShowInfo("计算曲面交线有误");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }

        // 曲面沿法线偏置
        private void btnOfsSurf_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt != 1)
                {
                    ShowInfo("请输入一个曲面的ID");
                    return;
                }

                int valcnt = ExtractDoubleValues(out List<double> vals);
                if (valcnt != 1)
                {
                    ShowInfo("请输入曲面偏置的距离");
                    return;
                }

                UInt64 surfIdFst = ids[0];
                double dis = vals[0];
                VfHRESULT status = VFAdapter.vfOffsetSurface(surfIdFst, dis, out UInt64 outSurfId);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo("曲面沿法线偏置成功，新的曲面ID为:" + outSurfId);
                }
                else
                {
                    ShowInfo("曲面沿法线偏置成功有误");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }
        // 镜像曲面
        private void btnMiSurf_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt != 2)
                {
                    ShowInfo("请先输入一个曲面的ID，再输入一个镜像参考平面的ID");
                    return;
                }


                UInt64 surfIdFst = ids[0];
                UInt64 refPlnId = ids[1];
                bool bReserved = chkReserve.IsChecked.HasValue ? chkReserve.IsChecked.Value : false;

                VfHRESULT status = VFAdapter.vfMirrorSurface(surfIdFst, refPlnId, bReserved, out UInt64 outSurfId);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo("曲面镜像成功，新的曲面ID为:" + outSurfId);
                }
                else
                {
                    ShowInfo("曲面镜像失败");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }
        // 样条曲线
        private void btnSpCv_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt < 4)
                {
                    ShowInfo("请输入至少四个点的ID");
                    return;
                }
                UInt64[] vcIds = new UInt64[ids.Count()];
                for (int i = 0; i < ids.Count(); i++)
                {
                    vcIds[i] = ids[i];
                }
                bool isControlPoints = chkControlPoint.IsChecked.HasValue ? chkControlPoint.IsChecked.Value : false;

                VfHRESULT status = VFAdapter.vfCreateSplineCurve(vcIds.ToArray(), ids.Count, isControlPoints, out UInt64 outCvId);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo("样条曲线创建成功，新的曲线ID为:" + outCvId);
                }
                else
                {
                    ShowInfo("样条曲线创建失败");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }
        // 边界填充曲面
        private void btnSurfFill_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt == 0)
                {
                    ShowInfo("请输入填充曲面的边界ID集合");
                    return;
                }

                UInt64[] ptIds = new UInt64[ids.Count];
                for (int i = 0; i < ids.Count; i++)
                {
                    ptIds[i] = ids[i];
                }

                VfHRESULT status = VFAdapter.vfCreateSurfaceByFill(ptIds, ptIds.Count(), out UInt64 outSurfId);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo("边界填充曲面创建成功，新的曲面ID为:" + outSurfId);
                }
                else
                {
                    ShowInfo("边界填充曲面创建失败");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }
        // 曲面上两点创建曲线
        private void btnCvOnSurf_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt != 3)
                {
                    ShowInfo("请依次输入两点的ID、曲面的ID");
                    return;
                }

                UInt64 idFirst = ids[0];
                UInt64 idSecond = ids[1];
                UInt64 idSurf = ids[2];

                VfHRESULT status = VFAdapter.vfCreateCurveOnSurfaceByTwoPoints(idFirst, idSecond, idSurf, out UInt64 outSurfId);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo("两点创建曲线成功，新的曲线ID为:" + outSurfId);
                }
                else
                {
                    ShowInfo("两点创建曲线失败");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }
        // 镜像曲线
        private void btnMiCv_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt != 2)
                {
                    ShowInfo("请先输入一个曲线的ID，再输入一个镜像参考平面的ID");
                    return;
                }


                UInt64 cvIdFst = ids[0];
                UInt64 refPlnId = ids[1];
                bool bReserved = chkReserve.IsChecked.HasValue ? chkReserve.IsChecked.Value : false;

                VfHRESULT status = VFAdapter.vfMirrorCurve(cvIdFst, refPlnId, bReserved, out UInt64 outCvId);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo("曲线镜像成功，新的曲线ID为:" + outCvId);
                }
                else
                {
                    ShowInfo("曲线镜像失败");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }
        // 投影创建曲线
        private void btnCvByProj_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt != 2)
                {
                    ShowInfo("请先输入一个曲线的ID，再输入一个曲面的ID");
                    return;
                }


                UInt64 cvIdFst = ids[0];
                UInt64 surfId = ids[1];

                VfHRESULT status = VFAdapter.vfCreateCurveByProjection(cvIdFst, surfId, out UInt64 outCvId);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo("投影曲线创建成功，新的曲线ID为:" + outCvId);
                }
                else
                {
                    ShowInfo("投影曲线创建失败");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }
        // 曲面加厚创建体
        private void btnVcByThken_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt != 1)
                {
                    ShowInfo("请先输入一个曲线的ID");
                    return;
                }

                int valcnt = ExtractDoubleValues(out List<double> vals);
                if (valcnt != 1)
                {
                    ShowInfo("请输入一个加厚值");
                    return;
                }
                double depth = vals[0];
                UInt64 surfId = ids[0];

                VfHRESULT status = VFAdapter.vfCreateBodyWithThickedSurface(surfId, depth, out UInt64 outById);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo("曲面加厚创建体成功，新的BodyID为:" + outById);
                }
                else
                {
                    ShowInfo("曲面加厚创建体失败");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }
        // 计算曲面周长和面积
        private void btnCalSurSL_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt != 1)
                {
                    ShowInfo("请输入一个曲线的ID");
                    return;
                }

                UInt64 surfId = ids[0];

                VfHRESULT statusA = VFAdapter.vfSurfaceArea(surfId, out double dArea);


                VfHRESULT statusP = VFAdapter.vfSurfacePerimeter(surfId, out double dPerimeter);
                if (statusA == VfHRESULT.vf_Success && statusP == VfHRESULT.vf_Success)
                {
                    ShowInfo(string.Format("曲面面积计算成功，面积为:{0:F4},曲面周长计算成功，周长为:{1:F4}", dArea, dPerimeter));
                }
                else if (statusA == VfHRESULT.vf_Success)
                {
                    ShowInfo(string.Format("曲面面积计算成功，面积为:{0:F4},曲面周长计算失败", dArea));
                }
                else if (statusP == VfHRESULT.vf_Success)
                { 
                    ShowInfo(string.Format("曲面周长计算成功，周长为:{0:F4},曲面面积计算失败", dPerimeter));
                }
                else
                {
                    ShowInfo("曲面面积和周长计算失败");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }
        // 多截面曲线创建面
        private void btnSurByLoft_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt < 2)
                {
                    ShowInfo("请至少输入两个截面曲线的ID");
                    return;
                }

                UInt64[] vcIds = new UInt64[ids.Count()];
                for (int i = 0; i < ids.Count(); i++)
                {
                    vcIds[i] = ids[i];
                }

                VfHRESULT status = VFAdapter.vfCreateSurfaceByLoft(vcIds.ToArray(), vcIds.Count(), out UInt64 outSurfId);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo("多截面曲线创建面成功，新的曲面ID为:" + outSurfId);
                }
                else
                {
                    ShowInfo("多截面曲线创建面失败");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }

        private void btnSurfMerge_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt < 2)
                {
                    ShowInfo("请至少输入两个曲面的ID");
                    return;
                }

                UInt64[] vcIds = new UInt64[ids.Count()];
                for (int i = 0; i < ids.Count(); i++)
                {
                    vcIds[i] = ids[i];
                }

                VfHRESULT status = VFAdapter.vfSurfaceMerge(vcIds.ToArray(), vcIds.Count(), out UInt64 outSurfId);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo("曲面合并成功，新的曲面ID为:" + outSurfId);
                }
                else
                {
                    ShowInfo("曲面合并失败");
                }
            }
            catch(Exception ex)
            {
                var s = ex.Message;
            }
        }
        // 计算封闭曲面重量
        private void btnCSurfWeight_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt != 1)
                {
                    ShowInfo("请至少输入一个闭合曲面的ID");
                    return;
                }

                VfHRESULT status = VFAdapter.vfSurfaceWeight(ids[0], out double outWeight);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo("封闭曲面重量计算成功，重量为:" + outWeight);
                }
                else
                {
                    ShowInfo("封闭曲面重量计算失败");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }

        public unsafe static UInt64 ReadUInt64(IntPtr ptr, int ofs)
        {
            try
            {
                byte* ptr2 = (byte*)(void*)ptr + ofs;
                if (((int)ptr2 & 7) == 0)
                {
                    return *(UInt64*)ptr2;
                }

                UInt64 result = default(UInt64);
                byte* ptr3 = (byte*)(&result);
                *ptr3 = *ptr2;
                ptr3[1] = ptr2[1];
                ptr3[2] = ptr2[2];
                ptr3[3] = ptr2[3];
                ptr3[4] = ptr2[4];
                ptr3[5] = ptr2[5];
                ptr3[6] = ptr2[6];
                ptr3[7] = ptr2[7];
                return result;
            }
            catch (NullReferenceException)
            {
                throw new AccessViolationException();
            }
        }

        private void btnSelMut_Click(object sender, RoutedEventArgs e)
        {
            // 多选
            try
            {
                int selIdx = cbFilterType.SelectedIndex;
                GeomEntityType filterType = ConvertFileType(selIdx);
                if (filterType == GeomEntityType.vf_geom_none)
                {
                    ShowInfo("未处理的索引");
                    return;
                }
                bool preSelection = chkPreselection.IsChecked.HasValue ? chkPreselection.IsChecked.Value : false;
                string promptStr = ContructPromptStr(filterType,true);
                VfHRESULT status = VFAdapter.vfSelectMul(filterType,out int ptCount,out IntPtr pPts, promptStr, preSelection);
                if (status == VfHRESULT.vf_Success)
                {
                    string msg = "已选中对象";
                    for (int i = 0; i < ptCount; i++)
                    {
                        UInt64 pointId = ReadUInt64(pPts, i * sizeof(UInt64));
                        msg += string.Format("{0}{1}", pointId,(i==ptCount-1)?"":",");
                    }
                    ShowInfo(msg);
                    Marshal.FreeHGlobal(pPts);
                }
                else
                {
                    ShowInfo("已取消或未选中");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }


        }
        // 计算曲面重心
        private void btnSurfGra_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt != 1)
                {
                    ShowInfo("请输入一个曲面的ID");
                    return;
                }

                double[] dGravity = new double[3];
                VfHRESULT status = VFAdapter.vfCreateGravityOfSurface(ids[0],  dGravity);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo(string.Format("曲面重心计算成功，坐标为{0:F3},{1:F3},{2:F3}", dGravity[0], dGravity[1], dGravity[2]));
                }
                else
                {
                    ShowInfo("曲面重心计算失败");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }

        private void btnPtOnCv_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt != 2)
                {
                    ShowInfo("请先输入一个点的ID，再输入一个曲线的ID");
                    return;
                }

                bool bOn = false;
                VfHRESULT status = VFAdapter.vfTestPointOnCurve(ids[0], ids[1], out bOn);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo(bOn ? "点在线上" : "点不在线上");
                }
                else
                {
                    ShowInfo("点在线上计算失败");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }

        private void btnPtOnSurf_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt != 2)
                {
                    ShowInfo("请先输入一个点的ID，再输入一个曲面的ID");
                    return;
                }

                bool bOn = false;
                VfHRESULT status = VFAdapter.vfTestPointOnSurface(ids[0], ids[1], out bOn);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo(bOn ? "点在面上" : "点不在面上");
                }
                else
                {
                    ShowInfo("点在面上计算失败");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }



        private void btnGetPtOnSurf_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt != 1)
                {
                    ShowInfo("请仅输入一个面的ID");
                    return;
                }
                UInt64 faceId = ids[0];
                VfHRESULT status = VFAdapter.vfMousePtOnSurface(faceId,out double x,out double y,out double z);
                if(status == VfHRESULT.vf_Success)
                {
                    ShowInfo(string.Format("获得点:{0:F6},{1:F6},{2:F6}",x,y,z));
                }else
                {
                    ShowInfo("未选点或已取消");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }

        private void bntMiFaeture_Click(object sender, RoutedEventArgs e)
        {

            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt != 2)
                {
                    ShowInfo("请依次输入特征ID、镜像平面ID");
                    return;
                }

                UInt64 featureId =ids[0];
                UInt64 planeId =ids[1];
                bool bReserved = (chkReserve.IsChecked.HasValue) ? chkReserve.IsChecked.Value : true;
                VfHRESULT status = VFAdapter.vfMirrorObject(featureId, planeId, bReserved, out ulong mirroredFeatureId);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo(string.Format("镜像成功，镜像后的对象ID为{0}", mirroredFeatureId));
                }
                else
                {
                    ShowInfo("镜像失败");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }

        }

        private void btnCtCompCv_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt<1)
                {
                    ShowInfo("请输入曲线ID集");
                    return;
                }

                UInt64[] cvIds= ids.ToArray();
                bool bReserved = chkReserve.IsChecked.HasValue ? chkReserve.IsChecked.Value : true;
                VfHRESULT status = VFAdapter.vfCreateCurveByMultiCurves(cvIds,cvIds.Length,bReserved,out UInt64 outCvId);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo(string.Format("创建复合曲线成功,ID为{0}", outCvId));
                }
                else
                {
                    ShowInfo("创建复合曲线有误");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }

        private void btnTrimCv_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt !=2)
                {
                    ShowInfo("请分别输入被裁剪曲线、裁剪曲线ID");
                    return;
                }

                UInt64 trimedCvId = ids[0];
                UInt64 trimCvId =ids[1];

                UInt64[] cvIds = ids.ToArray();
                bool bReserved = chkReserve.IsChecked.HasValue ? chkReserve.IsChecked.Value : true;
                VfHRESULT status = VFAdapter.vfCurveTrim(trimedCvId, trimCvId, out UInt64 outTrimedCvId);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo(string.Format("裁剪曲线成功,曲线裁剪后ID为{0}", outTrimedCvId));
                }
                else
                {
                    ShowInfo("裁剪曲线有误");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }

        private void btnGetCvParaPt_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt != 1)
                {
                    ShowInfo("请输入一个曲线ID");
                    return;
                }
                
                int valueCnt =ExtractDoubleValues(out List<double> values);
                if (valueCnt != 1)
                {
                    ShowInfo("请输入参数U");
                    return;
                }

                UInt64 cvId = ids[0];
                double u =values[0];
                VfHRESULT status = VFAdapter.vfCreatePointOnCurve(cvId, u , out double x,out double y,out double z, out ulong pointID);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo(string.Format("在曲线上创建点成功,点ID为:{0},参数{1:F3}在曲线上的坐标为:{2:F3},{3:F3},{4:F3}", pointID,u,x,y,z));
                }
                else
                {
                    ShowInfo("在曲线上创建点有误");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }

        }

        private void bntGetSurfParaPt_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt != 1)
                {
                    ShowInfo("请输入一个曲面ID");
                    return;
                }

                int valueCnt = ExtractDoubleValues(out List<double> values);
                if (valueCnt != 2)
                {
                    ShowInfo("请输入参数U V");
                    return;
                }

                UInt64 cvId = ids[0];
                double u = values[0];
                double v = values[1];
                VfHRESULT status = VFAdapter.vfCreatePointOnSurface(cvId, u,v, out double x, out double y, out double z, out ulong pointID);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo(string.Format("在曲面上创建点成功,点ID为:{0},参数在曲面上的坐标为:{1:F3},{2:F3},{3:F3}", pointID, u, x, y, z));
                }
                else
                {
                    ShowInfo("在曲面上创建点有误");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }

        private void bntCtFuncCv_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int strCnt = ExtractString(out List<string> strs);
                if (strCnt != 3)
                {
                    ShowInfo("请输入三条表达式，以逗号分隔");
                    return;
                }

                int curCoordTypeIdx = cbCoordType.SelectedIndex;
                VfHRESULT status = VFAdapter.vfCreateFunctionCurve(curCoordTypeIdx, strs[0], strs[1], strs[2], out UInt64 outCvId);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo(string.Format("创建方程曲线成功,ID为{0}", outCvId));
                }
                else
                {
                    ShowInfo("创建方程曲线有误");
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }

        private void btnChWidClr_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt == 0)
                {
                    ShowInfo("请至少输入一个拓扑ID");
                    return;
                }

                List<IntPtr> idStrArr = new List<IntPtr>();
                foreach (UInt64 id in ids)
                {
                    idStrArr.Add(Marshal.StringToHGlobalAnsi(id.ToString()));
                }
                idStrArr.Add(IntPtr.Zero);

                IntPtr[] strArr = idStrArr.ToArray();
                VfHRESULT status = VFAdapter.vfChangeLineColorWidthInsertMap(strArr);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo("批量更改线宽颜色成功");
                }
                else
                {
                    ShowInfo("批量更改线宽颜色有误");
                }

                foreach (IntPtr ptr in idStrArr)
                {
                    if (ptr != IntPtr.Zero)
                        Marshal.FreeHGlobal(ptr);
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }

        private void btnRestoreWidClr_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt == 0)
                {
                    ShowInfo("请至少输入一个拓扑ID");
                    return;
                }
               
                List<IntPtr> idStrArr = new List<IntPtr>();
                foreach (UInt64 id in ids)
                {
                    idStrArr.Add(Marshal.StringToHGlobalAnsi(id.ToString()));
                }
                idStrArr.Add(IntPtr.Zero);

                IntPtr[] strArr = idStrArr.ToArray();
                VfHRESULT status = VFAdapter.vfChangeLineColorWidthFromMap(strArr);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo("批量恢复线宽颜色成功");
                }
                else
                {
                    ShowInfo("批量恢复线宽颜色有误");
                }
                foreach (IntPtr ptr in idStrArr)
                {
                    if (ptr != IntPtr.Zero)
                        Marshal.FreeHGlobal(ptr);
                }
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }

        private void btnCtCoord_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt != 3)
                {
                    ShowInfo("请输入三个对象ID,依次为面ID，点ID、线ID");
                    return;
                }
                int valueCnt = ExtractDoubleValues(out List<double> values);
                if (valueCnt != 3)
                {
                    ShowInfo("请输入三个数值，依次为起始角、方向角、线段长");
                    return;
                }

                bool isRightHandDir = (cbHnadDirection.SelectedIndex == 0);
                double stAngle = values[0];
                double dirAngle = values[1];
                double segLen = values[2];

                VfHRESULT status = VFAdapter.vfCreateRosetteById(ids[0], ids[1], ids[2], stAngle, dirAngle,segLen, isRightHandDir,out ulong rosetteId,out ulong line1,
                     out ulong line2, out ulong line3, out ulong line4, out ulong line5, out ulong line6);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo(string.Format("创建坐标系成功，六条边分别为:{0},{1},{2},{3},{4},{5},坐标系特征ID为{6}", line1, line2, line3, line4, line5, line6, rosetteId));
                }
                else
                {
                    ShowInfo("创建坐标系有误");
                }

            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }

        private void btnDelObj_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int idCnt = ExtractIds(out List<UInt64> ids);
                if (idCnt != 1)
                {
                    ShowInfo("请仅输入一个拓扑对象的ID");
                    return;
                }
                VfHRESULT status = VFAdapter.vfRemoveTargetObject(ids[0]);
                if (status == VfHRESULT.vf_Success)
                {
                    ShowInfo("删除拓扑对象成功");
                }
                else
                {
                    ShowInfo("删除拓扑对象失败");
                }
            }catch (Exception ex) {
                ShowInfo(ex.Message);
            }
        }

        private void btnSelectionToId_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                string filteTypeStr =tbInputStr.Text;
                if (filteTypeStr.Length == 0)
                {
                    ShowInfo("请输入过滤类型");
                    return;
                }
                IntPtr intV = Marshal.AllocHGlobal(sizeof(UInt64));
                VfHRESULT status = VFAdapter.vfSelectionToID(filteTypeStr, intV);
                if (status == VfHRESULT.vf_Success)
                {
                    ulong id;
                    unsafe
                    {
                        UInt64* pV = (UInt64*)intV;
                        id = *pV;
                    }
                    ShowInfo(string.Format("选择到:{0}", id));
                }
                else
                {
                    ShowInfo("根据过滤器筛选失败");
                }
                Marshal.FreeHGlobal(intV);
            }
            catch (Exception ex)
            {
                ShowInfo(ex.Message);
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {

        }

        private void btnSection3d_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                VfHRESULT status = VFAdapter.vfStartLinkWithCAD(TGC_CODE);
                string laminateName = "laminate004";
                string sectionCvName = 2322.ToString();
                string daPath = "CompositeDB.db";
                string componentType = "Ply";
                string boundaryType = "Net";
                string scaleType = "Scaled";
                string visStyle = "Draped";
                string profileType = cbProfileType.Text;
                VFAdapter.VF2Create3Dsection(laminateName,sectionCvName, componentType, boundaryType, 
                    scaleType, 100, 1.0, visStyle, profileType, 0, 0, false, "", true, daPath);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
          
        }

        private void btnDelTemporary_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                VfHRESULT status = VFAdapter.vfStartLinkWithCAD(TGC_CODE);
                status= VFAdapter.vf2DeleteTemporaryObjects();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void btnNote3d_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                string laminateName = "laminate004";
                string daPath = "CompositeDB.db";
                string componentType = "name/seq-step/orient/material";
                string summaryType = "Count/Thickness/percentage";
                string boundaryType = "Net";
                string noteName = "Note3d";
                string rosetteName = "Rosette";
                string headerText = laminateName;
                string origin = 71.ToString();
                string leader = 6798.ToString();
                int iLinesPerColumn =2;
                VfHRESULT status = VFAdapter.vfStartLinkWithCAD(TGC_CODE);
                status = VFAdapter.vf2Create3DNotes(noteName, laminateName, rosetteName, origin,
                    false, boundaryType, leader, summaryType, componentType, headerText, "-", iLinesPerColumn, true, daPath);
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }
    }
}
